/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Entity;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;

/**
 *
 * @author James
 */
@Entity
public class ReservableUnit implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long    id;
    private String  name;
    private String  description;
    private boolean active;
    private boolean deleted;
    //Variables to control free slots
    private int     currentMonth;
    private int     currentYear;
    private int     currentMonthArray;
    private int[][][] firstMonth;
    private int[][][] secondMonth;
    private int[][][] thirdMonth;
    private int[][][] fourthMonth;
    @ManyToOne
    private Files  layout;
    @OneToOne
    private Item   reservedItem;
    @ManyToOne
    private Outlet theOutlet;
    @OneToOne(cascade={CascadeType.PERSIST})
    private ReservableUnitDetails latestReservableUnitDetails;
    @OneToMany(cascade={CascadeType.PERSIST})
    private List<ReservableUnitDetails> listOfReservableUnitDetails;
    @OneToMany(cascade={CascadeType.ALL})
    private List<Files> listOfPictures;
    @OneToMany(cascade={CascadeType.PERSIST}, mappedBy="reservedUnit")
    private List<Reservation> listOfReservations; 

    public ReservableUnit() {
        this.active             = true;
        this.deleted            = false;
        this.currentMonthArray  = 1;
        this.listOfPictures     = new ArrayList<Files>();
        this.firstMonth         = new int[31][24][2];
        this.secondMonth        = new int[31][24][2];
        this.thirdMonth         = new int[31][24][2];
        this.fourthMonth        = new int[31][24][2];
        this.listOfPictures     = new ArrayList<Files>();
        this.listOfReservations = new ArrayList<Reservation>();
        this.listOfReservableUnitDetails = new ArrayList<ReservableUnitDetails>();
    }
    
    public void createReservableUnit(String name, String description, int numOfCustomersPerUnit, int numOfAvailableUnits, Files layout, Item reservedItem, Outlet theOutlet) {
        this.name                 = name;
        this.description          = description;
        this.layout               = layout;
        this.reservedItem         = reservedItem;
        this.theOutlet            = theOutlet;
        // Populate fields based on 
        DateTime date          = new DateTime(DateTimeZone.forID(theOutlet.getTimezone()));
        this.currentMonth      = date.getMonthOfYear();
        this.currentYear       = date.getYear();
        // Create the 1st ReservableUnitDetails
        ReservableUnitDetails rud = new ReservableUnitDetails();
        rud.createReservableUnitDetails(theOutlet.getReservationNoShowFee(), theOutlet.getReservationCancelFee(), theOutlet.getReservableMinimumLength(), theOutlet.getReservableMaximumLength(), theOutlet.getReservationMinimumLeadTime(), theOutlet.getReservationMaximumLeadTime(), numOfCustomersPerUnit, numOfAvailableUnits);
        this.listOfReservableUnitDetails.add(rud);
        this.latestReservableUnitDetails = rud;
        //Populate the arrays
        System.out.println("UNIT: " + numOfAvailableUnits);
        for (int i = 0 ; i < 4 ; i++) {
            int[][][] theMonth = this.getMonth(currentMonthArray+i);
            for (int j = 0 ; j < 31 ; j++) {
                for (int k = 0 ; j < 24 ; j++) {
                    for (int l = 0 ; l < 2 ; l++) {
                        theMonth[j][k][l] = numOfAvailableUnits;
                    }
                }
            }
        }
    }
    
    public void addPicture(Files thePicture) {
        this.listOfPictures.add(thePicture);
    }
    
    public void addReservation(Reservation theReservation) {
        this.listOfReservations.add(theReservation);
    }
    
    //Getters and Setters
    public void setNextMonth() {
        if (++this.currentMonthArray > 4) this.currentMonthArray = 1;
        if (this.currentMonthArray > 12) {
            this.currentMonth = 1;
            this.currentYear++;
        }
    }
    
    public int[][][] getMonth(int month) {//can only give reliable result if month is within [thisRealMonth; thisRealMonth + 4]
        int index = month - currentMonth + currentMonthArray;
        if (index < 0) index = index + 12;
        if (index > 4) index = index - 4;
        if (index == 1) return firstMonth;
        else if (index == 2) return secondMonth;
        else if (index == 3) return thirdMonth;
        else if (index == 4) return fourthMonth;
        else return null;
    }

    public void setMonth(int month, int[][][] monthArray) {
        int index = month - currentMonth + currentMonthArray;
        if (index < 0) index = index + 12;
        if (index > 4) index = index - 4;
        if (index == 1) this.firstMonth = monthArray;
        else if (index == 2) this.secondMonth = monthArray;
        else if (index == 3) this.thirdMonth  = monthArray;
        else if (index == 4) this.fourthMonth = monthArray;
    }
    
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
          
    public int[][][] getFirstMonth() {
        return firstMonth;
    }

    public void setFirstMonth(int[][][] firstMonth) {
        this.firstMonth = firstMonth;
    }

    public int[][][] getFourthMonth() {
        return fourthMonth;
    }

    public void setFourthMonth(int[][][] fourthMonth) {
        this.fourthMonth = fourthMonth;
    }

    public int[][][] getSecondMonth() {
        return secondMonth;
    }

    public void setSecondMonth(int[][][] secondMonth) {
        this.secondMonth = secondMonth;
    }

    public int[][][] getThirdMonth() {
        return thirdMonth;
    }

    public void setThirdMonth(int[][][] thirdMonth) {
        this.thirdMonth = thirdMonth;
    }

    public ReservableUnitDetails getLatestReservableUnitDetails() {
        return latestReservableUnitDetails;
    }

    public void setLatestReservableUnitDetails(ReservableUnitDetails latestReservableUnitDetails) {
        this.latestReservableUnitDetails = latestReservableUnitDetails;
    }

    public Outlet getOutlet() {
        return theOutlet;
    }

    public void setOutlet(Outlet theOutlet) {
        this.theOutlet = theOutlet;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Files getLayout() {
        return layout;
    }

    public void setLayout(Files layout) {
        this.layout = layout;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<ReservableUnitDetails> getListOfReservableUnitDetails() {
        return listOfReservableUnitDetails;
    }

    public void setListOfReservableUnitDetails(List<ReservableUnitDetails> listOfReservableUnitDetails) {
        this.listOfReservableUnitDetails = listOfReservableUnitDetails;
    }

    public Item getReservedItem() {
        return reservedItem;
    }

    public void setReservedItem(Item reservedItem) {
        this.reservedItem = reservedItem;
    }

    public int getCurrentMonth() {
        return currentMonth;
    }

    public void setCurrentMonth(int currentMonth) {
        this.currentMonth = currentMonth;
    }

    public int getCurrentMonthArray() {
        return currentMonthArray;
    }

    public void setCurrentMonthArray(int currentMonthArray) {
        this.currentMonthArray = currentMonthArray;
    }

    public int getCurrentYear() {
        return currentYear;
    }

    public void setCurrentYear(int currentYear) {
        this.currentYear = currentYear;
    }

    public List<Files> getListOfPictures() {
        return listOfPictures;
    }

    public void setListOfPictures(List<Files> listOfPictures) {
        this.listOfPictures = listOfPictures;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    public boolean isDeleted() {
        return deleted;
    }

    public void setDeleted(boolean deleted) {
        this.deleted = deleted;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof ReservableUnit)) {
            return false;
        }
        ReservableUnit other = (ReservableUnit) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "Entity.ReservationUnit[ id=" + id + " ]";
    }
    
}
